import numpy as np
import random as rm
import math

class BIM:
    def __init__(self,matrix,Fuzzymatrix1,Fuzzymatrix2,Fuzzymatrix3):
        self.matrix=np.array(matrix)
        self.Fuzzymatrix1=np.array(Fuzzymatrix1,dtype=float)
        self.Fuzzymatrix2=np.array(Fuzzymatrix2,dtype=float)
        self.Fuzzymatrix3=np.array(Fuzzymatrix3,dtype=float)

    def normal1(self,matrix1, matrix2, matrix3):
        matrix1 = np.array(matrix1)
        matrix2 = np.array(matrix2)
        matrix3 = np.array(matrix3)

        m, n = matrix1.shape
        for i in range(m):
            for j in range(n):
                s=sum(matrix3[:,j])
                matrix1[i][j] =float(matrix1[i][j]/s)
        return matrix1

    def normal2(self,matrix1, matrix2, matrix3):
        matrix1 = np.array(matrix1)
        matrix2 = np.array(matrix2)
        matrix3 = np.array(matrix3)
        m, n = matrix2.shape
        for i in range(m):
            for j in range(n):
                matrix2[i][j] =(matrix2[i][j] / sum(matrix2[:,j]))
        return matrix2

    def normal3(self,matrix1, matrix2, matrix3):
        matrix1 = np.array(matrix1)
        matrix2 = np.array(matrix2)
        matrix3 = np.array(matrix3)

        m, n = matrix3.shape
        for i in range(m):
            for j in range(n):
                matrix3[i][j] =(matrix3[i][j] / sum(matrix1[:,j]))
        return matrix3

    def getfuzzy(self,matrix, matrix1, matrix2, matrix3):
        m, n = (np.array(matrix).shape)
        for i in range(m):
            for j in range(n):
                if matrix[i][j] < matrix1[i][j] or matrix[i][j] > matrix3[i][j]:
                    matrix[i][j] = 0
                elif matrix1[i][j] <= matrix[i][j] <= matrix2[i][j]:
                    matrix[i][j] = (matrix[i][j] - matrix1[i][j]) / (matrix2[i][j] - matrix1[i][j])
                elif matrix2[i][j] <= matrix[i][j] <= matrix3[i][j]:
                    matrix[i][j] = (matrix3[i][j] - matrix[i][j]) / (matrix3[i][j] - matrix2[i][j])
        return matrix

    def get_V(self):

        # 求得D'
        matrix = self.getfuzzy(self.matrix, self.Fuzzymatrix1, self.Fuzzymatrix2, self.Fuzzymatrix3)
        # 模糊决策数组归一化
        #print(self.Fuzzymatrix1)
        #print(self.Fuzzymatrix2)
        #print(self.Fuzzymatrix3)
        matrix1 = self.normal1(self.Fuzzymatrix1, self.Fuzzymatrix2, self.Fuzzymatrix3)
        matrix2=self.normal2(self.Fuzzymatrix1, self.Fuzzymatrix2, self.Fuzzymatrix3)
        matrix3=self.normal3(self.Fuzzymatrix1, self.Fuzzymatrix2, self.Fuzzymatrix3)
        # 求V
        matrix = self.getfuzzy(matrix, matrix1, matrix2, matrix3)

        return matrix

    def get_weight(self):
        matrix=self.matrix
        m, n = matrix.shape
        list_weight = []
        for i in range(n):
            Sj = 0
            for j in range(m):
                s = sum(matrix[:, i])
                fij = matrix[j][i] / s
                Sj += (fij * (math.log(fij)))
            list_weight.append(Sj)
        for i in range(n):
            list_weight[i] = list_weight[i] / sum(list_weight)
        return list_weight

    def getfianlV(self):
        weight=self.get_weight()
        matrix=self.get_V()
        matrix=np.array(matrix)
        m, n = matrix.shape
        final_list = []
        for i in range(n):
            for j in range(m):
                matrix[j][i] = matrix[i][j] * weight[i]

        for i in range(m):
            d1 = 0
            d2 = 0
            for j in range(n):
                d1 += (matrix[i][j] - max(matrix[:, j]))
                d2 += (matrix[i][j] - min(matrix[:, j]))
            print(d1,d2)
            d1 = math.sqrt(d1)
            d2 = math.sqrt(d2)

            final_list.append(d2 / (d1 - d2))
        return final_list